<?php

if(!defined('IN_DISCUZ')) {
	exit('Access Denied');
}

class SMS {
	var $CONF = array();
	var $CONF_url = '';
	var $CONF_clienid = ''; //配置项 运营商客户端ID
	var $CONF_username = ''; //配置项 运营商帐号
	var $CONF_password = ''; //配置项 运营商密码
	var $CONF_signature = ''; //配置项 申请的签名
	var $CONF_POST = array();
	var $CONF_badlist = array();
	var $CONF_apiservice = '';
	var $CONF_callback_func = array('wd','cl');
	var $CONF_send_debug = 0; //是否返回原始数据 调试使用
	
	//以下内容请勿修改，否则将会导致功能异常
	var $mobile = ''; //手机号码
	var $Status = 0; // 1=允许发送
	var $Error = 0; // 错误代码
	var $Max = 10; //同一个号码每日允许发送最大数量
	var $NFT = 3; //同一个号码连续失败发送最大次数
	var $Spacing = 90; //两次发送间隔
	var $today_Overage_num = 0; //当日同号码剩余发送量
	var $User_Spacing = 0; //用户两次发送间隔剩余时间
	var $User_late_data = array(); //最近一次发送数据
	var $SID = 0; //最新验证码sid
	var $CODE = ''; //最新验证码
	var $Content = ''; //短信内容
	var $Modules = array(); //允许的动作标识
	var $CN = 1;
	var $Code_Num = 5; //验证码位数
	var $Modules_ID = 0;
	
	function __construct() {
		global $_G;
		if($_G['setting']['sms'] && !is_array($_G['setting']['sms'])) $_G['setting']['sms'] = (array)dunserialize($_G['setting']['sms']);
		$config = $_G['setting']['sms'];
		if($config['apiservice'] =='close'){
			$this->Error = 93;
			return false;
		}
		$this->CONF = $config;
		$this->CONF_apiservice = in_array($config['apiservice'],$this->CONF_callback_func) ? $config['apiservice'] : '';
		$this->CONF_clienid = $config['clienid'];
		$this->CONF_username = $config['username'];
		$this->CONF_password = $config['password'];
		if(!$this->CONF || !$this->CONF_apiservice || !$config['content'] || !$this->CONF_username || !$this->CONF_password){
			$this->Error = 94;
			return false;
		}
		
		$this->Content  = trim($config['content']);
		$this->CONF_signature  = $config['signature'];
		$this->Max  = intval($config['sendmax']);
		$this->NFT  = intval($config['sendnft']);
		$this->Spacing  = intval($config['sendtime']);
		$this->Code_Num  = intval($config['numbers']);
		$this->Code_Num = !$this->Code_Num ? 6 : ($this->Code_Num > 10 ? 10 : $this->Code_Num);
		$this->Modules = $config['sendpage'];
		
		
		if($config['badlist']){
			foreach($config['badlist'] as $k => $value){
				$value = preg_replace("/[^0-9\*]/",'',$value);
				if($value){
					$value = str_replace('*','\d',$value);
					$this->CONF_badlist[] = $value;
				}
			}
		}
		unset($config);
	}
	
	function modules($modules){
		if($this->Modules[$modules]){
			$this->Modules_ID = $modules;
			return $this->Modules_ID;
		}else{
			return false;
		}
	}
	
	function mobile_format($mobile){
		$mobile = preg_replace("/[^0-9]/",'',$mobile);
		if($this->CN){
			if(strlen($mobile) != 11){
				$mobile = '';
			}elseif(!preg_match("/1[3|4|5|7|8]\d{9}/i",$mobile)){
				$mobile = '';
			}
		}
		$this->mobile = $mobile;
		return $mobile;
	}
	
	function check($mobile,$code,$modules,$uid){
		global $_G;
		
		if($this->Error) return false;
		
		$code = preg_replace("/[^0-9]/",'',$code);
		if(strlen($code) != $this->Code_Num){
			return false;
		}
		$this->mobile_format($mobile);
		if(!$this->mobile){
			return false;
		}
		
		$data = C::t('common_smscode')->get_mobile_late($this->mobile,'0');
		
		if($modules && $this->Modules[$modules] && $data['modules'] != $modules){
			return false;
		}
		
		if(!isset($uid)) $uid = $_G['uid'];
		if($data && $code == $data['code']){
			C::t('common_member_status')->update($uid, array('mobilechecklastdate' => TIMESTAMP));
			C::t('common_smscode')->update($data['sid'],array('uid'=>$uid,'status'=>1,'checkip'=>$_G['clientip']));
			
			$token = slimtoken('ENCODE',$_G['member']['password'], array($data['sid'],TIMESTAMP,$_G['clientip'],$mobile,$code,$modules));
			dsetcookie('token_sms',$token,86400*30);
			return $data;
		}else{
			return false;
		}
	}
	
	function send($modules,$mobile){
		global $_G;
		
		if($this->Error) return false;
		if(!$this->modules($modules)){
			$this->Error = 98;
			return false;
		}
		$this->mobile_format($mobile);
		
		if(!$this->mobile){
			$this->Error = 3;
			return false;
		}
		if($this->CONF_badlist){
			foreach($this->CONF_badlist as $value){
				if($this->mobile == $value || preg_match("/".$value."/",$this->mobile)){
					$this->Error = 10;
					return false;
				}
			}
		}
		
		$this->send_check();
		
		if($this->Error){
			return false;
		}
		for($i=0; $i < $this->Code_Num; $i++){
			$this->CODE .= mt_rand(1,9);
		}
		$this->Content = str_replace('{CODE}',$this->CODE,$this->Content);
		
		
		$data = array();
		
		if($this->CONF_apiservice =='wd'){
			$data = $this->wd();
		}elseif($this->CONF_apiservice =='cl'){
			$data = $this->cl();
		}
		
		if($this->Error){
			return false;
		}
		if($data){
			if($this->CONF_send_debug){
				//调试模式返回原始数据
				return $data;
			}
			
			if($data['status'] == 1){
				//发送成功
				$insert = array(
					'uid' => $_G['uid'],
					'mobile'=> $this->mobile,
					'code' => $this->CODE,
					'dateline' => TIMESTAMP,
					'callback' => $data['callback'],
					'NFT' => 0,
					'modules' => $this->Modules_ID,
					'sendip' => $_G['clientip'],
				);
				if($this->User_late_data && $this->User_late_data['status'] ==0){
					//检查上一条验证码是否验证通过 如果没有 则记录连续失败次数
					$insert['NFT'] = $this->User_late_data['NFT'] +1;
				}
				$this->SID = C::t('common_smscode')->insert($insert,true);
				if($this->SID){
					return $this->SID;
				}else{
					$this->Error = 4;
					return false;
				}
			}else{
				$this->Error = 9;
				return false;
			}
		}
	}
	
	function cl(){
		if(CHARSET =='gbk'){
			$this->Content = diconv($this->Content,CHARSET,'UTF-8');
		}
		$this->CONF_url = 'http://sms.slimbbs.com/cl/send?account='.$this->CONF_username.'&pswd='.$this->CONF_password.'&mobile='.$this->mobile.'&msg='.urlencode($this->Content);
		$data = $this->curl();
		$return = array('status'=>0,'data'=>'');
		if($data){
			$olddata = $data;
			list($status,$taskID) = explode("\n",$data);
			list($date,$code) = explode(',',$status);
			$date = trim($date);
			$code = trim($code);
			$taskID = trim($taskID);
			if($date && $taskID && $code =='0'){
				$return = array('status'=>1,'callback'=>trim($taskID));
			}
			$return['data'] = $olddata;
		}
		
		return $return;
	}
	
	function wd(){//通道1 返回XML格式
		$this->Content .= $this->CONF_signature;
		if(CHARSET =='gbk'){
			$this->Content = diconv($this->Content,CHARSET,'utf-8');
		}
		$this->CONF_url = 'http://sms.slimbbs.com/wd/send?userid='.$this->CONF_clienid.'&account='.urlencode($this->CONF_username).'&password='.urlencode($this->CONF_password).'&content='.urlencode($this->Content).'&mobile='.$this->mobile;
		
		$data = $this->curl();
		$return = array('status'=>0,'data'=>'');
		if($data){
			$olddata = $data;
			$data = simplexml_load_string($data);
			if($data){
				$data = json_decode(json_encode($data),true);
				if($data){
					if($data && $data['returnstatus'] =='Success' && $data['taskID']){
						$return = array('status'=>1,'callback'=>trim($data['taskID']));
					}
					$return['data'] = $olddata;
				}
			}
		}
		return $return;
	}
	
	function send_check(){
		global $_G;
		if($this->Error) return false;
		
		if(!$this->CONF_signature || mb_strlen($this->CONF_signature,CHARSET) >10){
			$this->Error = 1;
		}
		if(!$this->Content || mb_strlen($this->Content) >68){
			$this->Error = 2;
		}
		
		if(!$this->mobile){
			$this->Error = 3;
		}
		if(!$this->Error){
			$data = C::t('common_smscode')->get_mobile_late($this->mobile);
			if($_G['setting']['sms_sendtime']) $this->Spacing = $_G['setting']['sms_sendtime'];
			if($data && $data['status'] ==0 && $data['dateline'] > TIMESTAMP - $this->Spacing){
				//未验证且未达到发送间隔时间
				$this->User_Spacing = $this->Spacing - (TIMESTAMP - $data['dateline']);
				$this->User_Spacing = $this->User_Spacing <0 ? 0 : $this->User_Spacing;
				$this->Error = 6;
			}
			
			if($this->NFT >0 && !$this->Error && $data['status'] == 0 && $this->NFT -1 - $data['NFT'] <=0){
				//连续验证失败发送次数超过限制
				$this->Error = 7;
			}
			if(!$this->Error){
				//今日发送条数超过限制 则停止
				$sendnum = C::t('common_smscode')->count_by_mobile($this->mobile,TIMESTODAY);
				$this->today_Overage_num = $this->Max - $sendnum;
				if(!$this->Error && $this->today_Overage_num <= 0){
					$this->Error = 8;
				}
			}
			$this->User_late_data = $data;
			unset($data);
		}
	}
	
	function overage(){
		if($this->Error) return 0;
		
		$post_data = array(
			'userid' => $this->CONF_clienid,
			'account' => $this->CONF_username,
			'password' => $this->CONF_password
		);
		
		if($this->CONF_apiservice =='wd'){
			$this->CONF_url = 'http://sms.slimbbs.com/'.$this->CONF_apiservice.'/querybalance?userid='.$this->CONF_clienid.'&account='.urlencode($this->CONF_username).'&password='.urlencode($this->CONF_password);
			$data = $this->curl();
			$return = 0;
			if($data){
				$data = simplexml_load_string($data);
				if($data){
					$data = json_decode(json_encode($data),true);
					if($data && $data['returnstatus'] =='Sucess' && $data['overage']){
						$return = $data['overage'];
					}
				}
			}
		}elseif($this->CONF_apiservice =='cl'){
			$this->CONF_url = 'http://sms.slimbbs.com/'.$this->CONF_apiservice.'/querybalance?account='.$this->CONF_username.'&pswd='.$this->CONF_password;
			$data = $this->curl();
			$data = preg_split("/[,\r\n]/",$data);
			if($data['3']) $return = $data['3'];
		}
		
		return dintval($return);
	}
	
	function curl($post){
		if($this->Error) return false;
		
		$data = array();
		if(!$this->CONF_url){
			$this->Error = 99;
		}else{
			$c = Wclass('aliyun_gateWayAPI');
			$data = $c->Run('23390321','e133cd88d30fd56f54419d0e32cdf39d',$post?'POST':'GET',$this->CONF_url);
			if($data['data'] && $data['httpcode'] == '200'){
				$data = trim($data['data']);
				if($data){
					return $data;
				}else{
					$this->Error = 5;
				}
			}else{
				$this->Error = 4;
			}
		}
		return $data;
	}
	
}

?>